package com.silverhaze.diamond.client.utils.db;

import com.silverhaze.commons.db.datasource.DataSourceAction;
import com.silverhaze.commons.db.datasource.DataSourceListener;
import com.silverhaze.commons.db.datasource.ObjectEntity;
import com.silverhaze.commons.utils.collections.list.MetaList;
import com.silverhaze.diamond.common.entity.Customer;
import com.silverhaze.diamond.common.entity.Detail;
import com.silverhaze.diamond.common.entity.Service;
import com.silverhaze.diamond.common.entity.SystemUser;
import com.silverhaze.diamond.common.service.DataSourceServiceRemote;
import com.silverhaze.diamond.common.util.ServiceLocator;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Ivan Babanin
 * This part of code is strictly confidential.
 * © Magnificent Software Inc.
 */
public class ServiceDataSource implements DataSourceServiceRemote {
    private static ServiceDataSource instance;
    private List<DataSourceListener> listeners;

    private DataSourceServiceRemote dataService;

    private ServiceDataSource() {
        dataService = ServiceLocator.remoteLookup(DataSourceServiceRemote.class, DataSourceServiceRemote.NAME);

        listeners = new ArrayList<DataSourceListener>();
    }

    public void delete(ObjectEntity o) {
        dataService.remove(o);
        fireDataSourceChanged(o.getClass());
    }

    public long persist(ObjectEntity o) {
        long result = dataService.persist(o);

        if (result != -1) {
            fireDataSourceChanged(o.getClass());
        }

        return result;
    }

    public <T extends ObjectEntity> List<T> getBeans(Class<T> clazz) {
        return dataService.get(clazz);
    }

    public List<Customer> getCustomers() {
        return getBeans(Customer.class);
    }

    public List<SystemUser> getUsers() {
        return getBeans(SystemUser.class);
    }

    public List<Detail> getDetails() {
        return getBeans(Detail.class);
    }

    public void updateService(Service service) {
//        session = HibernateUtil.getSessionFactory().getCurrentSession();
//        session.beginTransaction();
//
//        Set<UsedDetail> usedDetails = service.getUsedDetailes();
//        for (CountedDetail detail : usedDetails) {
//            session.merge(detail);
//        }
//
//        Set<BrokenDetail> brokenDetails = service.getBrokenDetailes();
//        for (BrokenDetail brokenDetail : brokenDetails) {
//            session.merge(brokenDetail);
//        }
//
//        service = (Service) session.merge(service);
//
//        service.setBrokenDetailes(brokenDetails);
//        service.setUsedDetailes(usedDetails);
//
//        fireDataSourceChanged(Service.class);

//        session.merge(service);

//        session.getTransaction().commit();
    }

    public boolean update(ObjectEntity objectEntity) {
//        session = HibernateUtil.getSessionFactory().getCurrentSession();
//        session.beginTransaction();
//
//        session.merge(objectEntity);
//
//        session.getTransaction().commit();

        dataService.update(objectEntity);
        fireDataSourceChanged(objectEntity.getClass());

        return true;
    }

    public void fireDataSourceChanged(Class clazz) {
        for (DataSourceListener listener : listeners) {
            listener.valuesUpdated(clazz, null, DataSourceAction.UPDATE);
        }
    }

    public void removeDataSourceListener(DataSourceListener listener) {
        if (listener != null && listeners.contains(listener)) {
            listeners.remove(listener);
        } else {
            throw new IllegalStateException("dataSource listener");
        }
    }


    public static ServiceDataSource getInstance() {
        if (instance == null) {
            instance = new ServiceDataSource();
        }

        return instance;
    }


    // todo: optimize
    public void cleanAllByClass(Class clazz) {
        //noinspection unchecked
        for (Object entity : getBeans(clazz)) {
            delete((ObjectEntity) entity);
        }
    }

    public void clean(Class clazz) {/*
        session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();

        session.createQuery("delete " + clazz.getName());

        session.getTransaction().commit();*/
    }

    public void remove(ObjectEntity o) {
    }

    public <T extends ObjectEntity> MetaList<T> get(Class<T> clazz) {
        return dataService.get(clazz);
    }

    public <T extends ObjectEntity> T get(Class<T> clazz, int id) {
        return null;
    }

    public List queryList(String query) {
        return null;
    }

    public Object queryUniqueResult(String query) {
        return null;
    }

    public void addDataSourceListener(DataSourceListener listener) {
    }
}
